package com.rc.saas.tenant.common.utils;

import java.util.ArrayList;
import java.util.List;

public class NumberUtil {
    private static String hexStr = "0123456789ABCDEF";

    private static String[] binaryArray = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000",
            "1001", "1010", "1011", "1100", "1101", "1110", "1111"};

    public static final String SPLIT = " ";

    /**
     * @return 二进制数组转换为二进制字符串 2-2
     */
    public static String bytes2BinStr(byte[] bArray) {

        String outStr = "";
        int pos = 0;
        for (byte b : bArray) {
            // 高四位
            pos = (b & 0xF0) >> 4;
            outStr += binaryArray[pos];
            // 低四位
            pos = b & 0x0F;
            outStr += binaryArray[pos];
        }
        return outStr;
    }

    /**
     * @param bytes
     * @return 将二进制数组转换为十六进制字符串 2-16    等同 转ASCII码
     */
    public static String bin2HexStr(byte[] bytes) {

        String result = "";
        String hex = "";
        for (int i = 0; i < bytes.length; i++) {
            // 字节高4位
            hex = String.valueOf(hexStr.charAt((bytes[i] & 0xF0) >> 4));
            // 字节低4位
            hex += String.valueOf(hexStr.charAt(bytes[i] & 0x0F));
            result += hex + " ";
        }
        return result.trim();
    }

    /**
     * @param hexString
     * @return 将十六进制转换为二进制字节数组 16-2
     */
    public static byte[] hexStr2BinArr(String hexString) {
        // hexString的长度对2取整，作为bytes的长度
        int len = hexString.length() / 2;
        byte[] bytes = new byte[len];
        byte high = 0;// 字节高四位
        byte low = 0;// 字节低四位
        for (int i = 0; i < len; i++) {
            // 右移四位得到高位
            high = (byte) ((hexStr.indexOf(hexString.charAt(2 * i))) << 4);
            low = (byte) hexStr.indexOf(hexString.charAt(2 * i + 1));
            bytes[i] = (byte) (high | low);// 高地位做或运算
        }
        return bytes;
    }

    /**
     * @param hexString
     * @return 将十六进制转换为二进制字符串 16-2
     */
    public static String hexStr2BinStr(String hexString) {
        return bytes2BinStr(hexStr2BinArr(hexString));
    }

    /**
     * 两个二进制求和
     *
     * @param a
     * @param b
     * @return
     */
    public static String addBinary(String a, String b) {
        int carry = 0;
        int sum = 0;
        int opa = 0;
        int opb = 0;
        StringBuilder result = new StringBuilder();
        while (a.length() != b.length()) {
            if (a.length() > b.length()) {
                b = "0" + b;
            } else {
                a = "0" + a;
            }
        }
        for (int i = a.length() - 1; i >= 0; i--) {
            opa = a.charAt(i) - '0';
            opb = b.charAt(i) - '0';
            sum = opa + opb + carry;
            if (sum >= 2) {
                result.append((char) (sum - 2 + '0'));
                carry = 1;
            } else {
                result.append((char) (sum + '0'));
                carry = 0;
            }
        }
        if (carry == 1) {
            result.append("1");
        }
        return result.reverse().toString();
    }

    /**
     * 一堆二进制求和
     *
     * @return
     */
    public static String binarySum(String[] hexStrs) {
        List<String> binList = new ArrayList<String>();
        for (int i = 0; i < hexStrs.length; i++) {
            binList.add(hexStr2BinStr(hexStrs[i]));
        }

        String first = null;
        String second = null;
        for (int i = 0; i < binList.size(); i++) {
            if (i == 0) {
                first = binList.get(0);
                continue;
            }
            second = binList.get(i);
            first = addBinary(first, second);
        }
        StringBuilder result = new StringBuilder(first);
        String newRes = result.reverse().toString();
        StringBuilder result2 = new StringBuilder(newRes.substring(0, 8));
        return result2.reverse().toString();
    }



    /**
     * 一堆二进制求和
     *
     * @return
     */
    public static String binarySumByAll(String[] hexStrs) {
        List<String> binList = new ArrayList<String>();
        for (int i = 0; i < hexStrs.length; i++) {
            binList.add(hexStr2BinStr(hexStrs[i]));
        }

        String first = null;
        String second = null;
        for (int i = 0; i < binList.size(); i++) {
            if (i == 0) {
                first = binList.get(0);
                continue;
            }
            second = binList.get(i);
            first = addBinary(first, second);
        }
        return first;
    }

    /**
     * 二进制转十进制
     *
     * @param binStr
     * @return
     */
    public static int binToTen(String binStr) {
        int x = 0;
        for (char c : binStr.toCharArray())
            x = x * 2 + (c == '1' ? 1 : 0);
        return x;
    }

    /**
     * 校验码生成
     */
    public static String checkNum(String[] strs) {

        // 二进制求和
        String bin = binarySum(strs);

        // 二进制转十进制
        int ten = binToTen(bin);

        // 对256求模
        int yu = ten % 256;

        // 十进制转十六进制
        return Integer.toHexString(yu).toUpperCase();
    }


    /**
     * 高低位换位
     *
     * @param str
     * @return
     */
    public static String lowHighChange(String str) {
        String a = str.substring(0, 2);
        String b = str.substring(3, 5);
        return b + " " + a;
    }


    /**
     * 获取校验码生成完整报文;
     *
     * @param data 校验码之前的报文数据;
     * @return
     */
    public static String getData(String data, String s) {
        data = data.trim();
        StringBuilder sb = new StringBuilder(data);
        sb.replace(3, 15, s);
        String checkNum = checkNum(sb.toString().split(" "));
        if (checkNum.length() < 2)
            checkNum = checkNum + "0";
        return sb.toString() + SPLIT + checkNum + SPLIT + "16";
    }

    public static void main(String args[]) throws Exception {
		/*StringBuilder result = new StringBuilder();
		File file = new File("D:/aa.txt");
		BufferedReader br = new BufferedReader(new FileReader(file));// 构造一个BufferedReader类来读取文件
		String s = null;
		String data = null;
		while ((s = br.readLine()) != null) {// 使用readLine方法，一次读一行
			data = "68 19 00 11 00 02 00 68 A1 00 00";
			System.out.println(NumberUtil.getData(data,s));
			data = "68 19 00 11 00 02 00 68 A4 09 00 01 01 02 00 00 00 00 00 00";
			System.out.println(NumberUtil.getData(data,s)+"\n\n");
		}
		//br.close();*/
        //String aa = "66 00 00 00 00 00 31 31 35 33 34 34 30 30 30 30 32 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 46 0A 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00";
        //System.out.println(checkNum(aa.split(" ")));
        //System.out.println(NumberUtil.hexStr2BinStr("1000"));
        String aa = "68 02 00 0E FF FF FF FF FF FF 10 01";
        System.out.println(aa);
        System.out.println("二进制和："+NumberUtil.checkNum(aa.split(" ")));

        System.out.println("十六进制："+NumberUtil.bin2HexStr("1151300000000000".getBytes()));

    }
}
